import msgspec
from litestar import Controller, get, post
from litestar.contrib.sqlalchemy.repository import SQLAlchemyAsyncRepository
from litestar.di import Provide
from litestar.pagination import OffsetPagination
from litestar.repository.filters import LimitOffset
from sqlalchemy.ext.asyncio import AsyncSession

from model.user import User
from schema.user import CreateUserForm


class UserRepository(SQLAlchemyAsyncRepository[User]):
    model_type = User


async def provide_user_repo(db_session: AsyncSession) -> UserRepository:
    return UserRepository(session=db_session)


class UserController(Controller):
    path = "/user"
    tags = ["user"]
    dependencies = {
        "user_repo": Provide(provide_user_repo),
    }

    @get("")
    async def get_users(
        self,
        user_repo: UserRepository,
        limit_offset: LimitOffset,
    ) -> OffsetPagination[User]:
        results, total = await user_repo.list_and_count(limit_offset)
        return OffsetPagination[User](
            items=results,
            total=total,
            limit=limit_offset.limit,
            offset=limit_offset.offset,
        )

    @post("")
    async def create_author(
        self,
        user_repo: UserRepository,
        data: CreateUserForm,
    ) -> User:
        obj = await user_repo.add(User(**msgspec.structs.asdict(data)))
        await user_repo.session.commit()
        return obj
